1 DS4B 101-R: R FOR BUSINESS ANALYSIS —-

2 INTERACTIVE PLOTS —-

3 GOAL: DEVELOP INTERACTIVE PLOTS FOR A SALES REPORT

4 LIBRARIES & DATA —-

# Main
library(tidyverse)
library(lubridate)

# Visualization
library(tidyquant)
library(plotly)

bike_orderlines_tbl <- read_rds("00_data/bike_sales/data_wrangled/bike_orderlines.rds")

5 1.0 TOTAL SALES BY MONTH —-

6 1.1 Preparing Time Series Data —-

total_sales_m_tbl <- bike_orderlines_tbl %>% 
    select(order_date, total_price) %>% 
    mutate(date_rounded = floor_date(order_date, unit = "month")) %>% 
    group_by(date_rounded) %>% 
    summarise(total_sales = sum(total_price)) %>% ungroup() %>% 

    # Create a lebl field
    # Remeber anything in the brackets are R code
    mutate(label_text = str_glue("Sales: {scales::dollar(total_sales)}
                                 Date: {date_rounded %>% format('%B %Y')}"))

7 Formatting Dates

"2011-01-01 00:00:00" %>% as_datetime() %>% format("")
## [1] "2011-01-01"

8 1.2 Interactive Plot —-

9 Step 1: Create ggplot with text feature

g1 <- total_sales_m_tbl %>% 
    ggplot(aes(x = date_rounded, y = total_sales)) +
    
    # Geoms
    geom_point(aes(text = label_text), colour = "#2C3E50") +
    geom_smooth(method = 'loess', span = 0.2) +
    
    # formatting
    theme_tq() +
    scale_y_continuous(labels = scales::dollar_format(scale = 1e-6, suffix = "M")) +
    labs(
        title = "Total Sales",
        y = "Revenue (USD)",
        x = "Date"
    )

g1

10 Step 2: Use ggplotly()

11 Setting Up Hover Text

12 [1] aes(text = label_text) in ggplot

13 [2] tooltip = “text” in ggplotly

ggplotly(g1, tooltip = "text")

14 1.3 Plot Total Sales Function —-

plot_total_sales <- function(unit = "month",
                             date_format = '%B %Y',
                             interactive = TRUE) {
    # handle Data 
    data_tbl <- bike_orderlines_tbl %>% 
        select(order_date, total_price) %>% 
        mutate(date_rounded = floor_date(order_date, unit = unit)) %>% 
        group_by(date_rounded) %>% 
        summarise(total_sales = sum(total_price)) %>% ungroup() %>% 
        
        # Create a lebl field
        # Remeber anything in the brackets are R code
        mutate(label_text = str_glue("Sales: {scales::dollar(total_sales)}
                                 Date: {date_rounded %>% format(date_format)}"))
    # Make the plot
    g <- data_tbl %>% 
        ggplot(aes(x = date_rounded, y = total_sales)) +
        
        # Geoms
        geom_point(aes(text = label_text), colour = "#2C3E50") +
        geom_smooth(method = 'loess', span = 0.2) +
        
        # formatting
        theme_tq() +
        scale_y_continuous(labels = scales::dollar_format(scale = 1e-6, suffix = "M")) +
        labs(
            title = "Total Sales",
            y = "Revenue (USD)",
            x = ""
        )
    
    # Static vs Interactive Logic 
    if (interactive) {
        return(ggplotly(g, tooltip = "text"))
    } else {
        return(g)
    }
    
}

15 1.4 Test Our Function —-

plot_total_sales(unit = "month", date_format = '%B %d, %Y', interactive = TRUE)

16 2.0 CATEGORY 2 SALES BY MONTH —-

17 2.1 Preparing Time Series Data —-

category_2_sales_m_tbl <- bike_orderlines_tbl %>% 
    select(order_date, category_1, category_2, total_price) %>% 
    mutate(date_rounded = floor_date(order_date, unit = "month")) %>% 
    
    group_by(date_rounded, category_1, category_2) %>% 
    summarise(total_sales = sum(total_price)) %>% ungroup() %>% 
    
    mutate(label_text = str_glue("Sales: {scales::dollar(total_sales)}
                                Date: {date_rounded %>% format('%B %Y')}")) %>% 
    mutate(category_2 = as_factor(category_2) %>% fct_reorder2(date_rounded, total_sales))

18 2.2 Interactive Plot —-

g2 <- category_2_sales_m_tbl %>% 
    ggplot(aes(date_rounded, total_sales, colour = category_2)) +
    geom_point(aes(text = label_text)) +
    geom_smooth(method = 'loess', span = 0.2) +
    facet_wrap(~category_2, scales = "free_y", ncol = 3) +
    
    # Protips: it is a good ideas to include expand_limits(y = 0)
    # When plotting time series. This ensures the magnitude of the time series
    # is porperly shown 
    expand_limits(y = 0) + 
    theme_tq() +
    theme(legend.position = "none",
          strip.text.x = element_text(margin = margin(5, 5, 5, 5, unit = "pt"))) +
    scale_y_continuous(label = scales::dollar_format(scale = 1e-3, suffix = "K")) +
    scale_colour_tq() +
    labs(
        title = "Bike Total Sales By Category 2",
        x = "",
        y = "Revenue (USD)",
    )

19 Step 2: Use ggplotly()

ggplotly(g2, tooltip = "text")

20 2.3 Plot Categories Function —-

plot_categories <- function(category_1 = "All", category_2 = "All",
                           unit = "month",
                           date_format = "%B %Y",
                           # n = number of columns
                           ncol = n,
                           scales = "free_y",
                           interactive = TRUE) {
    # Handle the data
    data_tbl <- bike_orderlines_tbl %>% 
        select(order_date, category_1, category_2, total_price) %>% 
        mutate(date_rounded = floor_date(order_date, unit = unit)) %>% 
        
        group_by(date_rounded, category_1, category_2) %>% 
        summarise(total_sales = sum(total_price)) %>% ungroup() %>% 
        
        mutate(label_text = str_glue("Sales: {scales::dollar(total_sales)}
                                Date: {date_rounded %>% format(date_format)}")) %>% 
        mutate(category_2 = as_factor(category_2) %>% fct_reorder2(date_rounded, total_sales))
    
    # Handle Inputs
    cat_1_text <- str_to_lower(category_1)
    cat_2_text <- str_to_lower(category_2)
    
    # Create filter logic
    if(cat_1_text != "all"){
        data_tbl <- data_tbl %>% 
            filter(category_1 %>% 
                       str_to_lower() %>% 
                       str_detect(pattern = cat_1_text))
    }
    
    if(cat_2_text != "all"){
        data_tbl <- data_tbl %>% 
            filter(category_2 %>% 
                       str_to_lower() %>% 
                       str_detect(pattern = cat_2_text))
    }
    
    # make the plot 
    g2 <- data_tbl %>% 
        ggplot(aes(date_rounded, total_sales, colour = category_2)) +
        geom_point(aes(text = label_text), colour = palette_light()[1]) +
        geom_smooth(method = 'loess', span = 0.2) +
        facet_wrap(~category_2, scales = scales, ncol = ncol) +
        
        # Protips: it is a good ideas to include expand_limits(y = 0)
        # When plotting time series. This ensures the magnitude of the time series
        # is porperly shown 
        expand_limits(y = 0) + 
        theme_tq() +
        theme(legend.position = "none",
              strip.text.x = element_text(margin = margin(5, 5, 5, 5, unit = "pt"))) +
        scale_y_continuous(label = scales::dollar_format(scale = 1e-3, suffix = "K")) +
        scale_colour_tq() +
        labs(
            title = "Bike Total Sales By Category 2",
            x = "",
            y = "",
        )
    
    # Create Static VS Interactive Logic 
    if (interactive) {
        return(ggplotly(g2, tooltip = "text"))
    } else {
        return(g2)
    }
}

21 2.4 Test Our Function —-

plot_categories(category_1 = "all", 
                category_2 = "(cross country|Elite|Trail)", 
                unit = "month",
                ncol = 1,
                scales = "fixed",
                interactive = TRUE)
plot_categories(category_1 = "all", 
                category_2 = "all", 
                unit = "month",
                ncol = 3,
                date_format = "%Y-%m-%d",
                interactive = TRUE)

22 3.0 SAVE FUNCTIONS —-

fs::file_create("01_Scripts/plot_sales.R")

dump(list = c("plot_total_sales", "plot_categories"), file = "01_Scripts/plot_sales.R")